﻿function TextBox(id) {
    this.text_print_state = false;
    this.textBox_state = false;
    this.text_print_text = null;
    var draw_end_callback = null;
    var text_context = null;
    var text_boxInterval = null;
    var text_array = null;
    var arg = new Object();
    var boxIsHide = true;
    var textIndex = 0;
    var text_canvas = document.getElementById(id);
    //box
    var text_box = {
        w: 600,
        h: 90,
        img: config.textBox_image,
        animate_span: 8
    }
    //text
    var text_box_text = {
        every_show_pix: 8,
        font_sizePx: 20,
        row_max: 22,
        drawX: 35,
        drawY: 15,
        drawY_span: 5
    }
    text_box_text.font = "bold " + text_box_text.font_sizePx.toString() + "px Arial, Helvetica, sans-serif";
    text_box_text.drawY2 = text_box_text.drawY;
    //nextImage
    var nextImageObj = {
        img: config.textBox_next_image,
        x: null,
        y: null,
        w: 60,
        h: 20
    }
    //    var text_box_Alpha = 0.77;
    //    var borderImageData = (function () {
    //        var bordercanvas = document.createElement("canvas");
    //        bordercanvas.width = text_box.img.width;
    //        bordercanvas.height = text_box.img.height;
    //        var borderContext = bordercanvas.getContext("2d");
    //        borderContext.drawImage(text_box.img, 0, 0);
    //        var imageData = borderContext.getImageData(0, 0, bordercanvas.width, bordercanvas.height);
    //        //没有透明通道的图片将过滤某种颜色使其透明
    //        for (var i = 0; i < imageData.data.length; i = i + 4) {
    //            if (imageData.data[i] == 0 && imageData.data[i + 1] == 0 && imageData.data[i + 2] == 0) {
    //                imageData.data[i + 3] = 255 * text_box_Alpha;
    //            }
    //        }
    //        return imageData;
    //    })()
    //

    //----------------------------------------------
    //          Constructors
    //----------------------------------------------
    text_canvas.objArray = new Array();
    text_canvas.onmousemove = function (e) {
        if (!boxIsHide) {
            var x = Tool.Mouse.GetX(e, text_canvas);
            var y = Tool.Mouse.GetY(e, text_canvas);
            for (var i = 0; i < this.objArray.length; i++) {
                var obj = this.objArray[i];
                if (obj.mouseIn(x, y)) {
                    obj.mouseover();
                }
                else {
                    obj.mouseout();
                }
            }
        }
    }
    text_canvas.onclick = function (e) {
        if (!boxIsHide) {
            var x = Tool.Mouse.GetX(e, text_canvas);
            var y = Tool.Mouse.GetY(e, text_canvas);
            for (var i = 0; i < this.objArray.length; i++) {
                var obj = this.objArray[i];
                if (obj.mouseIn(x, y)) {
                    obj.click();
                    $stopPropagation(e);
                }
            }
        }
    }
    text_context = text_canvas.getContext("2d");
    //----------------------------------------------
    //          public
    //----------------------------------------------
    this.SetArg = function (parameters) {
        if (parameters) {
            for (var i in parameters) {
                arg[i] = parameters[i];
            }
        }
    }
    this.NewAnimateFun = function (funname) {

    }
    this.SetCallBack = function (callback) {
        draw_end_callback = callback;
    }
    this.DrawText = function (text) {
        if (!text || text == "") {
            Draw();
            return;
        }
        if (boxIsHide) {
            var _this = this;
            draw_end_callback = function () { _this.DrawText(text); }
            this.boxShow();
            return;
        }
        this.text_print_state = true;
        this.text_print_text = text;
        text_array = new Array();
        textIndex = 0;
        if (text.length > 0 && text.length <= text_box_text.row_max) {
            text_array[0] = text;
        }
        else {
            var row = Math.ceil(text.length / text_box_text.row_max);
            for (var i = 0; i < row; i++) {
                text_array[i] = text.substr(i * text_box_text.row_max, text_box_text.row_max);
            }
        }
        var _this = this;
        var position = 0;
        var position_add = 0;
        var textwidth = 0;
        var color = arg.Color || config.textColor;
        text = text_array[textIndex];
        //
        text_context.shadowColor = "rgba(" + color + ", 0.3)";
        text_context.shadowOffsetX = 3;
        text_context.shadowOffsetY = 3;
        text_context.shadowBlur = 2;
        text_context.font = text_box_text.font;
        text_context.textBaseline = "top";
        //
        textwidth = text_context.measureText(text).width + text_box_text.drawX;
        position_add = text_box_text.every_show_pix / textwidth;
        arg.Model = arg.Model || "None";
        switch (arg.Model) {
            case "None":
                text_box_text.drawY2 = text_box_text.drawY;
                break;
            case "Clear":
                arg.Model = "None";
                break;
            case "Br":
                text_box_text.drawY2 = text_box_text.drawY2;
                break;
            default:
                alert("Error:arg.Model(" + arg.Model + ")");
                break;
        }
        //
        drawStart();
        text_boxInterval = window.setInterval(function () {
            text_context.save();
            var gradient = getTextGradient(position, position + position_add, color, text_box_text.drawX, textwidth);
            if (gradient != null) {
                text_context.fillStyle = gradient;
                Draw(text, text_box_text.drawX, text_box_text.drawY2);
                position += position_add;
            }
            else {
                gradient = getTextGradient(1, 1, color, text_box_text.drawX, textwidth);
                text_context.fillStyle = gradient;
                Draw(text, text_box_text.drawX, text_box_text.drawY2);
                text_box_text.drawY2 = text_box_text.font_sizePx + text_box_text.drawY2 + text_box_text.drawY_span;
                if (text_array.length > 1 && textIndex < text_array.length - 1) {
                    textIndex++;
                    text = text_array[textIndex];
                    textwidth = text_context.measureText(text).width + text_box_text.drawX;
                    position_add = text_box_text.every_show_pix / textwidth;
                    position = 0;
                }
                else {
                    window.clearInterval(text_boxInterval);
                    drawEnd(textwidth, text_box_text.drawY2 - text_box_text.font_sizePx);
                    text_boxInterval = null;
                    _this.text_print_state = false;
                }
            }
            text_context.restore();
        }, (arg && arg.TimeSpan) || config.textShowTimeSpeed);
    }
    this.Stop = function () {
        if (this.text_print_state) {
            if (text_boxInterval) {
                window.clearInterval(text_boxInterval);
            }
            drawStart();
            var color = arg.Color || config.textColor;
            text_context.save();
            var gradient = getTextGradient(1, 1, color, text_box_text.drawX, 0);
            text_context.fillStyle = gradient;
            if (text_array.length > 0) {
                for (textIndex; textIndex < text_array.length; textIndex++) {
                    Draw(text_array[textIndex], text_box_text.drawX, text_box_text.drawY2);
                    text_box_text.drawY2 = text_box_text.font_sizePx + text_box_text.drawY2 + text_box_text.drawY_span;
                }
            }
            text_context.restore();
            var textCoordinate = measureTextCoordinate(text_array[text_array.length - 1], text_box_text.drawY2);
            drawEnd(textCoordinate.x, textCoordinate.y);
            this.text_print_state = false;
        }
    }
    this.Clear = function () {
        text_box_text.drawY2 = text_box_text.drawY;
        if (!boxIsHide) {
            drawStart();
            Draw();
            drawEnd(text_box_text.drawX, text_box_text.drawY2);
        }
    }
    this.boxHide = function () {
        if (!boxIsHide) {
            this.textBox_state = true;
            var _this = this;
            boxIsHide = true;
            drawStart();
            Tool.Animate.Box_Hide_Animate(text_box.img, text_canvas, function () {
                _this.textBox_state = false;
                drawEnd();
                draw_end_callback();
            }, 0, 0, text_box.img.width, text_box.img.height, config.boxAnimateTimeSpeed, text_box.animate_span);
        }
        else {
            draw_end_callback();
        }
    }
    this.boxShow = function () {
        if (boxIsHide) {
            this.textBox_state = true;
            boxIsHide = false;
            var _this = this;
            var x = text_box.w / 2, y = text_box.h / 2;
            drawStart();
            Tool.Animate.Box_Show_Animate(text_box.img, text_canvas, function () {
                DrawImageBox();
                drawEnd();
                _this.textBox_state = false;
                draw_end_callback();
            }, x, y, text_box.img.width, text_box.img.height, config.boxAnimateTimeSpeed, text_box.animate_span);
        }
        else {
            draw_end_callback();
        }
    }
    //----------------------------------------------
    //          private
    //----------------------------------------------
    function DrawImageBox(x, y, w, h) {
        text_context.save();
        Tool.ResetContext(text_context);
        if (x != null && y != null) {
            w = w || text_box.w - x;
            h = h || text_box.h - y;
            text_context.clearRect(x, y, w, h);
            text_context.drawImage(text_box.img, x, y, w, h, x, y, w, h);
        }
        else {
            text_context.clearRect(0, 0, text_box.w, text_box.h);
            text_context.drawImage(text_box.img, 0, 0);
        }
        //menu
        var menu = {
            w: 50,
            h: 15,
            x: text_box.img.width - 50,
            y: 10,
            objArray: TextBoxMenu.getMenuArray()
        }
        text_canvas.objArray.length = 0;
        Tool.Menu.Draw(text_box.img, text_context, menu, text_canvas.objArray, TextBoxMenu, -3, 3);
        text_context.restore();
    }
    function stopNextImage() {
        if (nextImageObj.animate) {
            nextImageObj.animate.stop();
            nextImageObj.animate = null;
        }
        if (nextImageObj.x != null && nextImageObj.y != null) {
            DrawImageBox(nextImageObj.x, nextImageObj.y);
            nextImageObj.x = null;
            nextImageObj.y = null;
        }
    }
    function getTextGradient(s, e, color, x, w) {
        if (s > 1 || e > 1)
            return null;
        //h = h || text_box_text.font_sizePx;
        var gradient = text_context.createLinearGradient(x, 0, w, 0);
        gradient.addColorStop(s, "rgba(" + color + ",1)");
        gradient.addColorStop(e, "rgba(" + color + ",0)");
        return gradient;
    }

    function Draw(text, x, y) {
        if (!text) {
            DrawImageBox();
        }
        else {
            DrawImageBox(x, y);
            text_context.fillText(text, x, y);
        }
    }
    function drawStart() {
        stopNextImage();
    }
    function drawEnd(x, y) {
        if (x != null && y != null) {
            var _this = this;
            nextImageObj.x = x + 20;
            nextImageObj.y = y;
            nextImageObj.animate = Tool.Animate.ImageAnimate(nextImageObj.img, text_canvas, nextImageObj.x, nextImageObj.y, nextImageObj.w, nextImageObj.h, "y", 300,
            function (dx, dy, dw, dh) {
                DrawImageBox(dx, dy, dw, dh);
            });
        }
    }
    function measureTextCoordinate(text, y0) {
        return { x: text_context.measureText(text).width + text_box_text.drawX, y: y0 - text_box_text.font_sizePx }
    }

}
var TextBoxMenu = function (m, context, img, x, y, w, h) {
    this.m = m;
    this.context = context;
    this.img = img;
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
}
TextBoxMenu.prototype.mouseIn = function (mx, my) {
    if (mx > this.x && mx < this.x + this.w && my > this.y && my < this.y + this.h)
        return true;
    else
        return false;
}
TextBoxMenu.prototype.drawStart = function (font, fillStyle) {
    this.context.save();
    Tool.ResetContext(this.context, font || "bold 12px/2 Arial, Helvetica, sans-serif", fillStyle);
    this.context.clearRect(this.x, this.y, this.w, this.h);
    this.context.drawImage(this.img, 0, 0, this.img.width, this.img.height, this.x, this.y, this.w, this.h);
    this.context.textAlign = "center";
}
TextBoxMenu.prototype.mouseover = function () {
    this.drawStart(null, "#FF7256");
    this.context.fillText(this.m.name, this.x + this.w / 2, this.y);
    this.context.restore();
}
TextBoxMenu.prototype.mouseout = function () {
    this.drawStart(null, "rgba(255, 255, 255, 1)");
    this.context.fillText(this.m.name, this.x + this.w / 2, this.y);
    this.context.restore();
}
TextBoxMenu.prototype.click = function () {
    this.m.onclick.call(this);
}
TextBoxMenu.getMenuArray = function () {
    var menu = new Array(
        {
            name: "Option",
            onclick: function () {
                alert(this.m.name);
            }
        },
        {
            name: "Save",
            onclick: function () {
                alert(this.m.name);
            }
        },
        {
            name: "Load",
            onclick: function () {
                alert(this.m.name);
            }
        },
        {
            name: "Exit",
            onclick: function () {
                alert(this.m.name);
            }
        }
        );
    return menu;
}